<template>
  <Modal
    :headerStyle="{ padding: '0' }"
    v-model:open="visibleRef"
    :footer="null"
    width="100%"
    :closable="false"
    :destroy-on-close="true"
    wrapClassName="bpmn-full-modal"
  >
    <template #title>
      <div class="bpmn-title">
        <HTabs
          @change="handleChangeTabs"
          class="no-bottom"
          v-model:active="tabType"
          :dataSource="tabList"
        />
        <BpmnTop @close="handleClose" @submit="handleSubmit" :spinning="spinning" />
      </div>
    </template>
    <Spin :spinning="spinning">
      <div v-show="tabType === 1" class="basic-info">
        <div class="left">
          <BasicLeft :height="'100%'" :dataSource="BasicMenusList" v-model:active="menuType" />
        </div>
        <div class="content">
          <div class="content-base" v-show="menuType === 1">
            <BasicInfo ref="basicRef" />
          </div>

          <Rights v-show="menuType === 2" ref="rightsRef" />
          <Roles v-show="menuType === 3" ref="rolesRef" />
          <Menus v-show="menuType === 4" ref="menusRef" />
          <Props v-show="menuType === 5" ref="propsRef" />
          <Quadratic v-show="menuType === 6" ref="quadraticRef" />
          <AppProperty v-show="menuType === 7" ref="appProperty" />
        </div>
      </div>
      <FormSettings ref="formsRef" v-show="tabType === 2" />

      <div class="bpmn-design" v-show="tabType === 3">
        <div class="bpmn-design-left"> </div>
        <div class="bpmn-design-content">
          <BpmnChart v-if="processXml" :xml="processXml" />
        </div>
        <BpmnRight v-if="processXml" :tabType="tabType" />
      </div>
    </Spin>
  </Modal>
</template>
<script lang="ts" setup name="BpmnModal">
  import { computed, watch, ref } from 'vue';
  import { Modal, Spin } from 'ant-design-vue';
  // import Designer from '/@/components/BpmnChart/src/components/Designer';
  // import Toolbar from '/@/components/BpmnChart/src/components/Toolbar';
  import { HTabs } from '/@/components/HTabs';
  import { tabList, BasicMenusList } from './drawer.data';
  import BasicLeft from './BasicLeft/index.vue';
  import BasicInfo from './BasicInfo/index.vue';
  import BpmnTop from './BpmnTop/index.vue';
  import { BpmnChart } from '/@/components/BpmnChart';

  import Menus from './Menus/index.vue';
  import Roles from './Roles/index.vue';
  import Rights from './rights/index.vue';
  import Props from './props/index.vue';
  import Quadratic from './Quadratic/index.vue';
  import AppProperty from './AppProperty/index.vue';
  import FormSettings from './FormSettings/index.vue';
  import BpmnRight from './BpmnRight/index.vue';
  import { getTemplateDataApi, saveTemplateDataApi } from '/@/api/config-center/bpmn-process';
  //import { xmlStr } from './xmlDemo';
  import EventEmitter from '/@/utils/bpmn/EventEmitter';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { isArray } from '/@/utils/is';

  import modelerStore from '/@/store/modules/bpmnModeler';
  import editorStore from '/@/store/modules/bpmnEditor';

  import { cloneDeep } from 'lodash-es';
  const modeler = modelerStore();
  const editor = editorStore();

  const props = defineProps({
    visible: Boolean,
    templateID: Number,
  });
  const emit = defineEmits(['update:visible', 'reload']);
  const visibleRef = computed({
    get: () => {
      return props.visible;
    },
    set: (val) => {
      emit('update:visible', val);
    },
  });
  watch(
    () => props.visible,
    (val) => {
      if (val) {
        init({ TemplateID: props.templateID });
      }
    },
  );

  watch(
    () => editor.bpmnXml,
    (val) => {
      if (val) {
        processXml.value = val;
      }
    },
  );

  // watch(
  //   () => editor.editorSettings.theme,
  //   (val) => {
  //     if (val) {
  //       processXml.value = editor.getInitEditBpmn[val];
  //       const activits = modeler.getActivities.slice(0, 2);
  //       modeler.setActivities(cloneDeep(activits) || []);
  //     }
  //   },
  // );
  const baseInfo = ref({});
  const basicRef = ref<any>(null);
  const menusRef = ref<any>(null);
  const rolesRef = ref<any>(null);
  const rightsRef = ref<any>(null);
  const propsRef = ref<any>(null);
  const formsRef = ref<any>(null);
  const quadraticRef = ref<any>(null);
  const appProperty = ref<any>(null);

  async function init(data) {
    processXml.value = '';
    spinning.value = true;
    try {
      const res = await getTemplateDataApi(data);
      console.log('%c====res', 'color:#5ea;font-size:30px;font-weight:bold', res);
      const ret = res.bpmnData.activities.map((item) => {
        item.R0 = [];
        item.rangeType = item.participant?.rangeType;
        // item.rangeComponentType = item.participant?.rangeComponentType;
        item.selectUserNum = item.participant?.selectUserNum;
        item.maxLimitedNum = item.participant?.maxLimitedNum;
        item.caculateReturnFlag = item.participant?.caculateReturnFlag;
        item.caculateFormula = item.participant?.caculateFormula;
        item.participantRange = item.participant?.participantRange;
        item.transLimit = item.handleContent?.transLimit;
        item.compareCont = item.handleContent?.compareCont;
        item.limitCompare = item.handleContent?.limitCompare;
        item.transLimitChoice = item.handleContent?.transLimitChoice;

        item.rights = [];
        if (item?.baseInfo?.rights && item?.baseInfo?.rights.length > 0) {
          item.rights = item?.baseInfo?.rights;
        }
        if (!item.remindAddFlag) {
          item.remindAddFlag = [];
        }
        const r = item.participant?.settings?.find((i) => i.type === 'R0');

        if (r) {
          item.R0 =
            r.participants?.map((i) => ({ value: i.id * 1, userCode: i.code, label: i.name })) ||
            [];
        } else {
          item.R0 = [];
        }
        const participants =
          item.participant?.settings?.filter((i) => i.type !== 'R0').map((el) => el.participants) ||
          [];
        item.participants = participants.flat();

        return item;
      });

      console.log('%c===ret', 'color:#7ae;font-size:30px;font-weight:bold', ret);
      modeler.setActivities(cloneDeep(ret) || []);
      modeler.setBaseInfo(res.bpmnData.baseInfo || {});
      modeler.setFlowInfo(res.bpmnData.flowInfo || {});

      // processXml.value = res.bpmnXml || xmlStr;
      processXml.value =
        props.templateID === 0
          ? editor.initEditBpmn[res.bpmnData.baseInfo?.theme ?? 1]
          : res.bpmnXml ?? editor.initEditBpmn[1];
      if (props.templateID !== 0) {
        basicRef.value.updateSchema({ field: 'theme', dynamicDisabled: true });
      }
      basicRef.value.setFieldsValue(res.bpmnData.baseInfo);
      if (res.bpmnData.appSetting) {
        res.bpmnData.appSetting.bindImg = res.bpmnData.appSetting.bindImg && [
          { url: res.bpmnData.appSetting.bindImg },
        ];
      }

      appProperty.value.setFieldsValue(res.bpmnData?.appSetting || {});
      formsRef.value.init(res.bpmnData.forms[0] || {});

      menusRef.value.setMenusTableData(res.bpmnData.menus || []);

      rolesRef.value.setRolesTableData(res.bpmnData.roles || []);
      rightsRef.value.setRightsTableData(res.bpmnData.rights || []);
      propsRef.value.setPropsTableData(res.bpmnData.props || []);
      quadraticRef.value.setQuadraticTableData(res.bpmnData.scripts || []);
      baseInfo.value = res.bpmnData.baseInfo;
    } catch (error) {
      console.error(error);
    } finally {
      spinning.value = false;
    }
  }

  // tab切换
  const tabType = ref(1);
  function handleChangeTabs({ value }) {
    if (value === 3 || value === 2) {
      modeler.setConfiguration({
        menus: menusRef.value.getMenusDataSource(),
        roles: rolesRef.value.getRolesDataSource(),
        props: propsRef.value.getPropsDataSource(),
        rights: rightsRef.value.getRightsDataSource(),
      });
    }
  }
  const spinning = ref(false);
  const processXml = ref<string>('');

  // 左侧栏
  const menuType = ref(1);

  const { createMessage } = useMessage();
  function handleClose() {
    EventEmitter.removeAllListeners('modeler-init');
    modeler.activeElement = undefined;
    modeler.activeElementId = undefined;
    modeler.nodeItem = null;
    menuType.value = 1;
    tabType.value = 1;
    basicRef.value.resetFields();
    formsRef.value.resetFields();
    appProperty.value.resetFields();
    formsRef.value.isUpdate = false;
    formsRef.value.code = '';
    emit('update:visible', false);
  }
  function setParticipants(participants: any[], type = 'P0', target: Indexable = []) {
    if (participants && participants.length) {
      target.push({
        type,
        participants,
      });
    }
  }

  //保存流程
  async function handleSubmit() {
    try {
      const base = await basicRef.value.validate();
      const formsData = await formsRef.value.validate();
      const appPropertyData = await appProperty.value.validate();
      if (isArray(appPropertyData.bindImg)) {
        appPropertyData.bindImg = appPropertyData.bindImg.map((i) => i.url).toString();
      }
      spinning.value = true;
      const { xml } = await modeler.getModeler!.saveXML({ format: true, preamble: true });

      const activities = JSON.parse(JSON.stringify(modeler.getActivities));
      console.log('activities--------------------------', activities);

      activities.forEach((item) => {
        const rArr = item.R0?.map((i) => ({ id: i.value, code: i.code, name: i.label }));
        const arr: any[] = [];

        if (rArr && rArr.length) {
          arr.push({
            type: 'R0',
            participants: rArr,
          });
        }
        const P0 = item.participants.filter(
          (el) => ![-2, -1].includes(el.orgType) && el.type === 2,
        );
        /**
         *
         * GENERAL(99,"综合成员");
         * orgType -1  拟稿人的
         *    type = 2  =》 R1
         * orgType -2  当前处理人的
         *    type = 2  =》 R2
         *  orgType 1  部门下的岗位
         *    type = 2  =》 P1 取 rid
         *  orgType = null
         *    type = 2  =》 P0
         *    type = 8 =》 U0
         *    type = 4  =》 U1
         *    type = 1  =》 U4
         */
        const P1 = item.participants.filter((el) => [1].includes(el.orgType) && el.type === 2);
        const R1 = item.participants.filter((el) => el.type === 2 && el.orgType === -1);
        const R2 = item.participants.filter((el) => el.type === 2 && el.orgType === -2);
        const U0 = item.participants.filter((el) => el.type === 8);
        const U1 = item.participants.filter((el) => el.type === 4);
        const U4 = item.participants.filter((el) => el.type === 1);

        setParticipants(P0, 'P0', arr);
        setParticipants(P1, 'P1', arr);
        setParticipants(R1, 'R1', arr);
        setParticipants(R2, 'R2', arr);
        setParticipants(U0, 'U0', arr);
        setParticipants(U1, 'U1', arr);
        setParticipants(U4, 'U4', arr);

        item.participant = {
          ...item.participant,
          rangeType: item.rangeType,
          // rangeComponentType: item.rangeComponentType,
          selectUserNum: item.selectUserNum,
          maxLimitedNum: item.maxLimitedNum,
          // caculateReturnFlag: item.caculateReturnFlag,
          // caculateFormula: item.caculateFormula,
          settings: arr,
          participantRange: item.participantRange,
        };

        item.handleContent = {
          ...item.handleContent,
          transLimit: item.transLimit,
          compareCont: item.compareCont,
          limitCompare: item.limitCompare,
          transLimitChoice: item.transLimitChoice,
        };
        if (item?.rights && item?.rights?.length) {
          item.baseInfo.rights = item?.rights;
        }
        delete item.R0;
        delete item.participants;
        delete item.rights;
        delete item.rangeType;
        // delete item.rangeComponentType;
        delete item.maxLimitedNum;
        delete item.selectUserNum;
        delete item.transLimit;
        delete item.compareCont;
        delete item.limitCompare;
        delete item.transLimitChoice;
        delete item.caculateReturnFlag;
        delete item.caculateFormula;
      });

      const params = {
        templateID: props.templateID,
        bpmnXml: xml,
        bpmnData: {
          baseInfo: { ...baseInfo.value, ...base },
          flowInfo: modeler.getFlowInfo,
          menus: menusRef.value.getMenusDataSource(),
          roles: rolesRef.value.getRolesDataSource(),
          props: propsRef.value.getPropsDataSource(),
          rights: rightsRef.value.getRightsDataSource(),
          scripts: quadraticRef.value.getQuadraticDataSource(),
          activities: activities,
          appSetting: appPropertyData,
          forms: [
            {
              ...formsData,
              returnData: formsRef.value.getReturnData(),
              relationData: formsRef.value.getRelationData(),
              modelId: formsRef.value.modelId,
            },
          ],
        },
      };
      console.log('%c提交参数===========', 'color:#587;font-size:30px;font-weight:bold', params);
      // return;
      await saveTemplateDataApi(params);
      createMessage.success('操作成功');
      handleClose();
      emit('reload');
    } catch (err: any) {
      if (err?.values) {
        if (err.values.hasOwnProperty('modelCode')) {
          err.errorFields.forEach((item) => {
            createMessage.warning(`表单设置-${item.errors[0]}`);
          });
        } else {
          err.errorFields.forEach((item) => {
            createMessage.warning(`基础信息-${item.errors[0]}`);
          });
        }
      }
      console.error(err);
    } finally {
      spinning.value = false;
    }
  }
</script>
<style lang="less" scoped>
  .bpmn-title {
    display: flex;
    justify-content: space-between;
    height: 56px;
    align-items: center;
    padding: 0 12px;

    .no-bottom {
      border: transparent !important;
      padding-left: 6px;

      ::v-deep(.h-tab) {
        padding: 17px 6px !important;
      }
    }
  }

  .basic-info {
    display: flex;
    box-sizing: border-box;
    position: relative;
    width: 100%;
    height: 100%;

    .content {
      width: calc(100% - 226px);
      height: 100%;
      overflow-y: auto;

      .content-base {
        height: 100%;
        max-height: calc(100vh - 68px);
        overflow-y: auto;
        overflow-x: hidden;
        background: url(../../../../assets/images/bpmn-process/content-bg.png) no-repeat;
        background-size: contain;
        background-position: right;
      }
    }
  }

  .bpmn-design {
    width: 100%;
    height: 100%;
    overflow: hidden;

    &-left {
      position: absolute;
      left: 0;
      top: 0;
      z-index: 99;
      width: 92px;
      height: 100%;
      background-color: #fff;
      //box-shadow: 4px 0px 12px 0px rgba(0, 0, 0, 0.12);
      border-right: 12px solid rgba(242, 243, 245, 1);

      &::after {
        content: '';
        display: block;
        position: absolute;
        right: -1px;
        height: 100%;
        top: 48px;
        width: 1px;
        z-index: 102;
        background: rgb(240, 242, 245);
      }
    }

    &-content {
      height: 100%;

      .tool {
        width: 100%;
        display: flex;
        height: 46px;
      }

      .design {
        width: calc(100% - 484px);
        height: calc(100% - 58px);
        border-bottom: 12px solid rgba(242, 243, 245, 1);
        margin-left: 92px;
        margin-top: 58px;
      }
    }
  }
</style>
<style lang="less">
  .bpmn-full-modal {
    .ant-modal {
      max-width: 100%;
      top: 0;
      padding-bottom: 0;
      margin: 0;
      overflow: hidden;
    }

    .ant-modal-content {
      display: flex;
      flex-direction: column;
      height: calc(100vh);
      padding: 0 !important;
    }

    .ant-modal-header {
      padding: 0;
      border-bottom: 12px solid rgba(242, 243, 245, 1);
    }

    .ant-modal-body {
      flex: 1;

      .ant-spin-nested-loading {
        height: 100%;

        .ant-spin-container {
          height: 100%;
        }
      }
    }
  }
</style>
